home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_02_09 / 2n09034a < prev    next >
Text File  |  1991-08-05  |  16KB  |  470 lines

  1. /**********************************************************
  2.  * MENUC.CTL - Allows you to dynamically change your       *
  3.  * CONFIG.SYS  configuration at boot time.                *
  4.  *                                                        *
  5.  * Add DEVICE = MENUC.CTL [Mx Tx "Text] to your CONFIG.SYS *
  6.  * just ahead of the first group of commands  you wish to *
  7.  * be able to menu.  The x in Tx is the seconds MENUC.CTL  *
  8.  * will pause for a keystroke before booting normally.    *
  9.  * x defaults to zero.  The x in Mx is the default menu   *
  10.  * number (1-8) that will be selected in a normal boot.   *
  11.  * x defaults to one.  The text after the " will be the   *
  12.  * first menu title.  All text after the " will be        *
  13.  * considered part of the title, so it must be the last   *
  14.  * parameter on the line.  The first title can be         *
  15.  * specified this way, or by putting the following        *
  16.  * construct immediately after the DEVICE=MENUC.CTL        *
  17.  *                                                        *
  18.  * Add DEVICE = MTITLE [Text] to give the boot menu       *
  19.  * selection a title to put on the screen.  Each          *
  20.  * MTITLE [Text] (up to * eight) will create a new menu   *
  21.  * selection.                                             *
  22.  *                                                        *
  23.  * Add DEVICE = MENUEND after the last command you wish   *
  24.  * to be able to menu.  MENUEND (like MTITLE) is a dummy  *
  25.  * device and must appear in CONFIG.SYS in order for      *
  26.  * MENUC.CTL to operate.                                   *
  27.  *********************************************************/
  28.  
  29. #include "GENERAL.H"
  30. #include "LIB.H"
  31.  
  32. typedef   struct {        /* The static part of a device */
  33.   BYTE    HEADER_LENGTH;  /* drivers request header. */
  34.   BYTE    UNIT_CODE;      /* See "Writing MS-DOS Device */
  35.   BYTE    COMMAND_CODE;   /* Drivers" by Robert S. Lai  */
  36.   WORD    STATUS;
  37.   double  RESERVED;
  38. } RQ_Header;
  39. typedef   struct {        /* The dynamic part of the    */
  40.   RQ_Header HEADER;       /* "INITIALIZE" request       */
  41.   BYTE      UNITS;        /* header to a device driver  */
  42.   WORD      *ENDING_OFFSET;
  43.   WORD      ENDING_SEGMENT;
  44.   char      far *ARGUMENTS;
  45. } Init_Header;
  46. typedef   struct {         /* Structure to keep track   */
  47.   WORD    str_len;         /* of location of Config.SYS */
  48.   char    menu;            /* commands to be dealt with */
  49.   char far *start;
  50. } Cmd_Rec;
  51.  
  52.  
  53. #define Last_Record -1
  54.         /* flag to indicate last cmd to process */
  55. #define row_start 9       /* menu start location */
  56. #define col_start 12
  57. #define normal    0x07    /* norman and inverse video */
  58. #define inverse   0x70    /* colors */
  59.  
  60. BYTE   row;     /* variables for screen positioning */
  61. BYTE   col;
  62.  
  63. extern WORD MENU_CTL_END;
  64.        /* end of resident portion of device driver */
  65. WORD   DOS_VERSION;
  66. extern Cmd_Rec _ENDDATA;
  67.        /* free memory location for dynamic allocation */
  68. Cmd_Rec near *MyStorage = &_ENDDATA;
  69.         /* set pointer to free memory */
  70. Cmd_Rec *Cmds;
  71.         /* make it a pointer to Config.Sys commands */
  72. void leave(void);     /* device driver exit point */
  73. void clean_up(void);
  74.      /* disable non selected Config.SYS commands */
  75. char far *make_coff(char far *Buf);
  76.      /* routine to convert non selected Config.Sys *
  77.       * commands to BREAK = OFF                    */
  78. void set_menu(BYTE m);    /* setup menu select text */
  79. void display_far(char far *Buf); /* display a far string */
  80. void xlat_ch(char test); /* make control chars visible */
  81. void menu_name(BYTE cmd);
  82. extern Init_Header far *REQUEST_OFFSET;
  83.        /* pointer to Device Request Header */
  84. BYTE   far *M_Buffer;   /* some global variables */
  85. BYTE   far *Buf_Start;
  86. BYTE   far *Control_End;
  87. BOOL   end_found = FALSE;
  88.        /* make sure there is a "DEVICE=MENUEND" */
  89. BOOL   modified;
  90.        /* flag to indicate display screen needs update */
  91.  
  92. WORD   key = 0;  /* keeps track of keyboard entry */
  93. WORD   junk;
  94. WORD   time = 0; /* default time and menu selection */
  95. BYTE   menu = 0;
  96. WORD   configs;  /* number of menus */
  97. char   test;     /* local char for testing */
  98. char   menu_end[] = "DMENUEND";
  99.        /* Used to find "DEVICE=MENUEND" */
  100. #define l_menuend sizeof(menu_end) - 1
  101. char   bmenu[] = "DMTITLE";
  102.        /* Used to find "DEVICE=MTITLE" */
  103. #define l_bmenu  sizeof(bmenu) - 1
  104. char   menut[7][70];
  105.        /* store the titles for upto 8 selections */
  106.  
  107.  
  108. // #define Debug = TRUE;
  109.  
  110. void main(void) {
  111.   WORD i;
  112.   BYTE j;
  113.   BYTE k;
  114.   BYTE m;
  115.  
  116.   REQUEST_OFFSET->ENDING_OFFSET = 0;
  117.   REQUEST_OFFSET->ENDING_SEGMENT = _CS;
  118.     /* tell MS-Dos where our resident portion ends */
  119.   M_Buffer = REQUEST_OFFSET->ARGUMENTS;
  120.     /* point to rest of Config.Sys Commands */
  121.   printstr("MENUC.CTL V1.0 (C) Dec. 6, 1990 by "
  122.            "Larry Weaver\n\r$");
  123.   /* print a start up line.  */
  124.   DOS_VERSION = dosversion(); /*get MS-Dos version number*/
  125.   if (DOS_VERSION < 0X200) {  /* must be greater than 2 */
  126.     printstr("Wrong Version of Dos, "
  127.               "requires 2X or greater\n\r$");
  128.     leave();
  129.   }
  130.   for (i=0;i < 8;i++) for (j=0;j < 2;j++) menut[i][j] = 0;
  131.     /* assume no menu selection titles */
  132.   for (;((*M_Buffer != LF) & (*M_Buffer != CR));M_Buffer++){
  133.  
  134. /* parse MENUC.CTL command line,  get default time, menu, *
  135.  * and title                                            */
  136.  
  137.     test = *M_Buffer;
  138.     #ifdef Debug
  139.     xlat_ch(test);
  140.     #endif
  141.     if (test == '"') { /* see if title 1 */
  142.       M_Buffer++;
  143.       for (j=1;(*M_Buffer != LF) & (*M_Buffer != CR);
  144.            M_Buffer++,j++) {
  145.         #ifdef Debug
  146.           xlat_ch(*M_Buffer);
  147.         #endif
  148.         menut[0][j] = *M_Buffer;
  149.       }
  150.       /* put text in menu array */
  151.       menut[0][j] = '\0';  /* add terminating 0 */
  152.       menut[0][0] = --j;     /* put length in first element */
  153.       break;
  154.     } else if (test == 'M') { /* see if default menu */
  155.       test = *(M_Buffer + 1);
  156.       if ((test > '0') & (test < '9')) menu = test - '1';
  157.     } else if (test == 'T') { /* see if default time */
  158.       test = *(M_Buffer + 1);
  159.       if ((test > '/') & (test < ':')) time = test - '0';
  160.     }
  161.   }
  162.   while ((*M_Buffer == CR) | (*M_Buffer == LF)) {
  163.     /* go to next command */
  164.     #ifdef Debug
  165.     xlat_ch(*M_Buffer);
  166.     #endif
  167.     M_Buffer++;
  168.   }
  169.   m = 0;
  170.   if (cmpsnf(M_Buffer,bmenu,l_bmenu)) {
  171.     /* see if next command is "DEVICE=MTITLE", if it is *
  172.      * set up title for menu 1                         */
  173.     #ifdef Debug
  174.       display_far(M_Buffer);
  175.     #endif
  176.     set_menu(m);
  177.   }
  178.   Buf_Start = M_Buffer;
  179.   i = 0;
  180.   while (!end_found) {
  181.  
  182. /* parse rest of Config.Sys commands looking for          *
  183.  * "DEVICE=MENUEND".  Will turn all unrecognized commands *
  184.  * into "BREAK=OFF" commands in the process.  Also parses *
  185.  * rest of menus, and sets up their titles for later      *
  186.  * selection.                                            */
  187.  
  188.     for (;(*M_Buffer == CR) | (*M_Buffer == LF);M_Buffer++) {
  189.       #ifdef Debug
  190.         xlat_ch(*M_Buffer);
  191.       #endif
  192.     }
  193.     test = *M_Buffer;
  194.     #ifdef Debug
  195.       display_far(M_Buffer);
  196.     #endif
  197.     Control_End = M_Buffer;
  198.     Cmds = MyStorage + i;
  199.     if (test == 'D') {
  200.       end_found = cmpsnf(M_Buffer,menu_end,l_menuend);
  201.       /*  check for "DEVICE=MENUEND" */
  202.       if (end_found) {
  203.         make_coff(M_Buffer);
  204.         /* deactivate the command line */
  205.         Cmds->menu = Last_Record;
  206.         break;
  207.       } else if (cmpsnf(M_Buffer,bmenu,l_bmenu)) {
  208.         /* check for "DEVICE=MTITLE".  If too many titles *
  209.          * then select menu 1 and leave.                 */
  210.         if (m < 7) {
  211.           set_menu(++m);
  212.           continue;
  213.         } else {
  214.           printstr("Too many menu selections.  Must be less"
  215.                    " than 9!\n\rHit any key to continue!$");
  216.           junk = get_key();
  217.           printstr("\n\r$");
  218.           set_menu(++m);
  219.           key = EnterKey;
  220.           menu = 0;
  221.           Cmds->menu = Last_Record;
  222.           clean_up();
  223.           leave();
  224.         }
  225.